<?php

namespace app\merchants\services;

use app\common\loader\ModelMerchant;
use app\common\loader\ModelShop;
use app\common\loader\Services;
use app\merchants\loader\Model;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\facade\Db;

/**
 * 商户订单明细表
 */
class OrderService
{

    /**
     * 订单列表
     * @param  $where |搜索条件
     * @param  $page |页码
     * @throws DbException
     */
    public function orderPage($where, int $page = 1, $count = 30)
    {
        $pagelist = ModelMerchant::Order()->orderPage($where, $page, $count);
        Services::Helper()->showListTitle($pagelist['data'], ['shop' => 'shop_id', 'merchant' => 'op_user']);
        return $pagelist;
    }

    /**
     * 订单详情
     * @param  $order_no |搜索条件
     * @throws Exception
     */
    public function orderInfo($order_no)
    {
        $info = ModelMerchant::Order()->orderInfo($order_no);
        if (empty($info)) {
            throw  new Exception('无该订单信息', API_ERROR);
        }
        Services::Helper()->showInfoTitle($info, ['shop' => 'shop_id', 'merchant' => 'op_user']);
        $info['detail'] = ModelMerchant::OrderDetail()->getList($order_no);

        return $info;

    }


    /**
     * @param array $data 订单信息
     * @param int $pro_num 订单
     * @param int $op_user
     * @param string $mer_id
     * @param bool $bTransferStock 是否转移库存  true:转移库存 不使用事务, false,验证数据,使用事务
     * @throws DbException
     * @throws Exception
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     */
    public function orderAdd(array $data, int $pro_num, int $op_user, string $mer_id, bool $bTransferStock = false)
    {
        try {

            if ($bTransferStock === false) {
                //获取商户当前的虚码数
                $stock = ModelMerchant::MerchantStock()->getStockInfo($mer_id);
                if ($stock['virtual_num'] < $pro_num) {
                    throw  new Exception('虚码库库存不足,请购买虚码后重新上单');
                }
                // 判断商品code是否有效
                $productCodes = array_column($data['data'], 'product_code');
                //导入替换id为code
                $validProductCode = ModelMerchant::Product()->where('mer_id', $mer_id)->whereIn('id', $productCodes)->column(null, 'code', 'id');
                if (count($productCodes) !== count($validProductCode)) {
                    $diffValues = array_diff($productCodes, $validProductCode);
                    throw  new Exception('商品货号' . implode(',', $diffValues) . '不存在');
                }
                //导入去除该赋值 将前端的ID改为: code
                foreach ($data['data'] as &$row) {
                    $row['product_code'] = $validProductCode[$row['product_code']];
                }
                Db::startTrans();
            }

            $this->add($mer_id, $data['shop_id'], $pro_num, $op_user, $data['data'], $data['memo'], 1);

            if ($bTransferStock === false) {
                Db::commit();
            }
            return '';
        } catch (Exception $e) {
            if ($bTransferStock === false) {
                Db::rollback();
            }
            throw $e;
        }

    }


    public function mergeArray($mer_id, $data = []): array
    {
        $shop_ids = ModelShop::Shop()->where('mer_id', $mer_id)
            ->column(null, 'id', 'code');
        $array = [];
        $order_nos = make_unique_no(PRODUCT_CODE_TYPE_VIRTUAL);
        $orderArray = [];
        foreach ($data as $key => $v){
            if (empty($v[0]) || empty($v[1]) || empty($v[2])) {
                continue;
            }
            if (!isset($shop_ids[$v[0]])) {
                throw  new Exception('店铺编号未找到' . $v[0], API_ERROR);
            }

            $dataAction  = [
                'order_no' => $order_nos . $key,
                'mer_id' => $mer_id,
                'shop_id' => $shop_ids[$v[0]],
                'product_code' => trim($v[1]),
                'num' => (int)trim($v[2]),
            ];

            if (!empty($orderArray[$v[0]]['num'])){
                $orderArray[$v[0]]['num'] += $v[2];
            }

            if (empty($orderArray[$v[0]])){
                $orderArray[$v[0]] = $dataAction;
            }


        }

        foreach ($data as $v) {
            if (empty($v[0]) || empty($v[1]) || empty($v[2])) {
                continue;
            }
            if (!isset($shop_ids[$v[0]])) {
                throw  new Exception('店铺编号未找到' . $v[0], API_ERROR);
            }
            $array[] = [
                'order_no' => $orderArray[$v[0]]['order_no'],
                'mer_id' => $mer_id,
                'shop_id' => $shop_ids[$v[0]],
                'product_code' => trim($v[1]),
                'num' => (int)trim($v[2]),
            ];
        }

        return [$orderArray,$array];
    }

    /**
     * 废弃-订单导出模板
     * @param $shopIds | 门店ids
     * @param $mer_id | 商户id
     * @return array
     * @throws DbException
     * @throws Exception
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     */
    public function orderExcelSend($shopIds, $mer_id): array
    {
        try {
            $where[] = ['mer_id', '=', $mer_id];
            $excel_data = ModelMerchant::Product()->list($where, 100, ['code', 'title', 'warn_num']);
            if (!$excel_data) {
                throw  new  Exception('导出失败!', API_ERROR);
            }
            $shop = ModelShop::Shop()->where('mer_id', $mer_id)
                ->whereIn('id', $shopIds)
                ->select();
            if (empty($shop)) {
                throw  new Exception('商户不存在', API_ERROR);
            }
            $num = count($shop);
            $list = [];
            for ($i = 0; $i <= $num - 1; $i++) {
                foreach ($excel_data as $vo) {
                    $vo['shop_code'] = $shop[$i]['code'] ?? '';
                    $list[] = $vo;
                }
            }
            return $list;
        } catch (Exception $e) {
            throw  $e;
        }
    }

    /**
     * 导入订单
     * @param  $data |订单数据
     * @param  $mer_id | 商户id
     * @param $op_user
     * @return string
     * @throws DataNotFoundException
     * @throws DbException
     * @throws Exception
     * @throws ModelNotFoundException
     */
    public function orderExcelAdd($data, $mer_id, $op_user,$orderData): string
    {
        $model = ModelMerchant::Order();
        try {

            $productData = $this->getExcelDataNum($data, 'product_code');
            if ($productData['product_num'] < 1) {
                throw  new  Exception('请先检查商品数量', API_ERROR);
            }
            $validProductCode = ModelMerchant::Product()->where('mer_id', $mer_id)->whereIn('code', $productData['codes'])
                ->whereRaw('delete_at is null')
                ->column(null, 'code', 'id');
            if ($productData['num'] !== count($validProductCode)) {
                $diffValues = array_diff($productData['codes'], $validProductCode);
                throw  new Exception('请核对商品编号' . implode(',', $diffValues) . '不存在');
            }

            $stock = ModelMerchant::MerchantStock()->getStockInfo($mer_id);
            if ($stock['virtual_num'] < $productData['product_num']) {
                throw  new Exception('虚码库库存不足,请购买虚码后重新上单');
            }
            $model->startTrans();
            $model->orderAddAll($orderData, '订单导入', $op_user);
            ModelMerchant::OrderDetail()->insertAll($data);
            $model->commit();
            return true;
        } catch (Exception $e) {
            $model->rollback();
            throw $e;
        }

    }

    /**
     * 确认提交
     * @param $order_ons
     * @param $mer_id
     * @param $admin_id
     * @param string $memo
     * @throws DataNotFoundException
     * @throws DbException
     * @throws Exception
     * @throws ModelNotFoundException
     */
    public function orderSubmit($order_ons, $mer_id, $admin_id, string $memo = ''): void
    {
        try {
            $orderNum = ModelMerchant::Order()->whereIn('order_no', $order_ons)
                ->where('mer_id', $mer_id)
                ->where('status', '<', 1)
                ->count('order_no');
            if ($orderNum !== count($order_ons)) {
                throw new Exception('订单已提交', API_ERROR);
            }
            $orderData = ModelMerchant::OrderDetail()->whereIn('order_no', $order_ons)
                ->where('mer_id', $mer_id)
                ->select();
            if (empty($orderData)) {
                throw new Exception('订单信息未找到', API_ERROR);
            }
            $order = [];
            foreach ($orderData as $v) {
                $order[$v['order_no']][] = $v;
            }

            Db::startTrans();
            foreach ($order as $v) {

                $num = array_sum(array_column($v, 'num'));
                $shop_id = $v[0]['shop_id'];
                Model::ShopStock()->shopSave(
                    $v,
                    $mer_id,
                    $shop_id
                );
                ModelMerchant::MerchantStock()->userVirtualEdit(
                    $mer_id,
                    2,
                    $num,
                    $memo,
                    $admin_id,
                    $shop_id
                );
            }

            ModelMerchant::Order()->whereIn('order_no', $order_ons)
                ->where('mer_id', $mer_id)
                ->update(null, ['status' => 1]);
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            throw $e;
        }

    }

    /**
     * 订单添加
     * @param $mer_id |商户id
     * @param $shop_id |门店id
     * @param $pro_num |数量
     * @param $op_user |操作人
     * @param $data |下单数据
     * @param $memo |备注
     * @throws DataNotFoundException
     * @throws DbException
     * @throws Exception
     * @throws ModelNotFoundException
     */
    private function Add($mer_id, $shop_id, $pro_num, $op_user, $data, $memo, $status = 0)
    {
        $order_on = ModelMerchant::Order()->orderAdd(
            $mer_id,
            $shop_id,
            $pro_num,
            $memo,
            $op_user,
            $status
        );
        //添加订单明细表 明细两种添加方式， 批量添加， 单个添加
        ModelMerchant::OrderDetail()->orderAdd(
            $order_on,
            $data,
            $shop_id,
            $mer_id,
        );


        Model::ShopStock()->shopSave(
            $data,
            $mer_id,
            $shop_id
        );

        ModelMerchant::MerchantStock()->userVirtualEdit(
            $mer_id,
            2,
            $pro_num,
            $memo,
            $op_user,
            $shop_id
        );


    }


    private function getExcelDataNum($data, $column = '', $type = 'product')
    {
        $codes = array_flip(array_column($data, $column));
        $num = count($codes);
        $ExcelData = [
            'codes' => array_flip($codes) ?? 0,
            'num' => $num ?? 0
        ];
        if ((string)$type === 'product') {
            $product_num = array_sum(array_column($data, 'num'));
            $ExcelData['product_num'] = $product_num;
        }

        return $ExcelData;
    }

    /**
     * 订单删除
     * @param $order_ons
     * @param $mer_id
     * @throws DataNotFoundException
     * @throws DbException
     * @throws Exception
     * @throws ModelNotFoundException
     */
    public function orderDel($order_ons, $mer_id): void
    {
        try {
            $orderModel = ModelMerchant::Order();
            $orderData = $orderModel->whereIn('order_no', $order_ons)
                ->where(['status' => 0 , 'mer_id' => $mer_id])
                ->select();
            if (empty($orderData) || count($orderData) !== count($order_ons)) {
                throw new Exception('请核对订单信息', API_ERROR);
            }

            Db::startTrans();
           $res =  $orderModel->removeOption()->whereIn('order_no', $order_ons)
                ->where(['status' => 0 , 'mer_id' => $mer_id])
                ->delete();
           if (!$res){
               throw  new Exception('服务器繁忙请稍后再试', API_ERROR);
           }
            $res = ModelMerchant::OrderDetail()->whereIn('order_no', $order_ons)
                ->where(['mer_id' => $mer_id])
                ->delete();
            if (!$res){
                throw  new Exception('服务器繁忙请稍后再试', API_ERROR);
            }
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            throw $e;
        }

    }

}
